import java.io.*;
import java.net.*;
import au.edu.uow.csci213quiz.*;
import java.util.*;


public class Client {
	private static BufferedReader breader;
	private Socket aSocket = null;
	private PrintWriter out = null;
	private BufferedReader in = null;
	private String hostName;
	private int port;
	private ObjectOutputStream objectOutStream;
	private ObjectInputStream objectInStream;


	
	Client(){
		aSocket = null;
		out = null;
		in = null;
	}
	
	Client(String hostName, int port){
		aSocket = null;
		out = null;
		in = null;
		this.hostName = hostName;
		this.port = port;
	}
	
	public void setServerParams(String hostName, int port){
		this.hostName = hostName;
		this.port = port;
	}
	
	public String getHostname(){
		return hostName;
	}
	
	public int getPort(){
		return port;
	}
	
	
	public String getUser(){
		breader = new BufferedReader(new InputStreamReader(System.in));
        String name=null;
		//Getting student details
        System.out.println("What is your name?");
        try{
			name = breader.readLine();;
        }
		catch (IOException e){
			System.out.println("error reading name");
			terminateConnection();
			System.exit(-1);
		}
		catch (NullPointerException e){
			System.err.println("error reading name - name is null");
			terminateConnection();
			System.exit(-1);
		}
		
		return name;
	}
	
	//REGISTER METHOD
	public void Register(String name)throws IOException{
		out.println("REGISTER "+name);
		if(in.readLine().equals("OK"))
			System.out.println("User Registration Successful");
		else{
			System.err.println("User Registration Failed");
			terminateConnection();
			System.exit(-1);
		}
		
		
	}
	
	//GET QUESTION OBJECT METHOD
	private void requestQuestionObject(){
		Object questionsObject = null;
		System.out.println("question request sent"); //stub
		try{
			
			//SEND REQUEST TO SERVER
			out.println("QUESTION");
			
			//READ RESPONSE FROM SERVER
			questionsObject=objectInStream.readObject();
			System.out.println("Question Object Recieved");
			
			//WAIT FOR SERVER TO SEND OK
			if(in.readLine().equals("OK"))
				System.out.println("Question Request Finished");
			else{
				System.err.println("Question Request Failed");
				terminateConnection();
				System.exit(-1);
			}
		}
		catch(ClassNotFoundException e){
			System.err.println("Failed to read question - "+e);
            terminateConnection();
			System.exit(-1);
		}
		catch(IOException e){
			System.err.println("Failed to send question - "+e);
            terminateConnection();
			System.exit(-1);
		}

	}
	
	
	//CONNECT TO SERVER METHOD
	public void connectServer(){
		//SETUP I/O STREAMS
		try {
            aSocket = new Socket(hostName, port);
            out = new PrintWriter(aSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(aSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host:"+hostName);
            System.exit(-1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: "+hostName+":"+port);
            System.exit(-1);
        }
		
		//SETUP QBJECT STREAMS
		try{
			objectOutStream = new ObjectOutputStream(aSocket.getOutputStream());
			objectOutStream.flush();
			objectInStream = new ObjectInputStream(aSocket.getInputStream());
		}
		catch(IOException e){
			System.err.println("Error! - couldn't open object I/O streams");
			System.exit(-1);
		}
		
		//STUB TO CHECK WHAT SERVER IS DOING
		try{
			System.out.println("Server: " + in.readLine());
		}
		catch(Exception e){
			System.err.println("Failed to read from server: "+hostName+":"+port);
            System.exit(-1);
        }
	}
	
	//BYE METHOD
	public void terminateConnection(){
		//send the BYE message to the server
		try{
			out.println("EXIT");
			out.close();
			in.close();
			breader.close();
			aSocket.close();
			objectOutStream.close();
			objectInStream.close();
		}
		catch(IOException e){
			System.err.println("failed to close socket: "+hostName+":"+port);
            System.exit(-1);
        }
		System.out.println("Disconneted from Server");
	}
	
	
	
	
	//MAIN
	public static void main(String[] args) throws IOException {
		Client aClient = new Client();
		
		if(args.length<1){
			aClient.setServerParams("localhost", 40214);
		}
		else{
			String tokens[] = args[0].split("\\:");
			//System.out.println(tokens[0]+":"+tokens[1]);		//stub to check the split was working
			if (tokens.length<2)								//if only the host name is given process that
				aClient.setServerParams(tokens[0],40214);
			else
				aClient.setServerParams("localhost", 40214);	//process host name and port if given

		}
		
		aClient.connectServer();								//command to connect to the server
		Student student = new Student();
        student.setName(aClient.getUser());
		try{
			aClient.Register(student.getName());	//register
		}
        catch (IOException e) {
            System.err.println("Comms fail with "+aClient.getHostname()+":"+aClient.getPort());
			System.err.println(e);
			aClient.terminateConnection();
			System.exit(-1);
        }
		catch (ClassCastException e) {
            System.err.println("Comms fail with "+aClient.getHostname()+":"+aClient.getPort());
			System.err.println(e);
			aClient.terminateConnection();
			System.exit(-1);
        }
		
		for(int i=0;i<=5;i++){
			//aClient.requestQuestionObject();		//request question object
			//questionText=aClient.getQuestionText();	//extract question text
			//choicesText=aClient.getChoicesText();	//extract choices test
			//System.out.println(questionText);		//print question text
			//System.out.println(choicesText);		//print choice text
			
		}
		
		aClient.terminateConnection();
	}
		
	
    
}

